package com.bo.lock.readWriteLock;

import java.util.Random;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @Author: gpb
 * @Date: 2024/9/5 9:45
 * @Description:
 */
public class IReentrantReadWriteLock {
    static final int SHARED_SHIFT = 16;

    private final static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    private final static ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
    private final static ReentrantReadWriteLock.ReadLock readLock = lock.readLock();

    public static void main (String[] args) throws InterruptedException {
        System.out.println("==============================================");
        System.out.println("MAX_COUNT = " + ((1 << SHARED_SHIFT) - 1));
        System.out.println("STATE >>> SHARED_SHIFT = " + ((65537 >>> SHARED_SHIFT)));
        System.out.println("==============================================");

        System.out.println("=====USE ReentrantReadWriteLock-> readLock=====");
        // 创建Random类实例
        Random random = new Random();

        // 设置随机数范围
        int min = 60000; // 最小值（包含）
        int max = 120000; // 最大值（包含）
        new Thread(() -> {
            readLock.lock();
            int randomNumber = random.nextInt(max - min + 1) + min;
            System.out.println(Thread.currentThread().getName() + " 获取到读锁资源,并睡眠：" + (randomNumber) + " s ");
            try {
                Thread.sleep(randomNumber);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                readLock.unlock();
            }
        }, "lock-r1").start();
        new Thread(() -> {
            readLock.lock();
            int randomNumber = random.nextInt(max - min + 1) + min;
            System.out.println(Thread.currentThread().getName() + " 获取到读锁资源,并睡眠：" + (randomNumber) + " s ");
            try {
                Thread.sleep(randomNumber);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                readLock.unlock();
            }
        }, "lock-r2").start();
        new Thread(() -> {
            readLock.lock();
            int randomNumber = random.nextInt(max - min + 1) + min;
            System.out.println(Thread.currentThread().getName() + " 获取到读锁资源,并睡眠：" + (randomNumber) + " s ");
            try {
                Thread.sleep(randomNumber);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                readLock.unlock();
            }
        }, "lock-r3").start();
        Thread.sleep( random.nextInt(max - min + 1) + min);
        readLock.lock();
        System.out.println(Thread.currentThread().getName() + " 获取到读锁资源");
        readLock.unlock();
        System.out.println("=====USE ReentrantReadWriteLock-> readLock=====");

        System.out.println("=====USE ReentrantReadWriteLock-> writeLock=====");
        new Thread(() -> {
            writeLock.lock();
            System.out.println(Thread.currentThread().getName() + " 获取到写锁资源,并睡眠：" + (60 * 60 * 1000) + " ");
            try {
                Thread.sleep(60 * 60 * 1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }finally {
                writeLock.unlock();
            }
        }, "lock-w1").start();
        Thread.sleep(2000);
        // 主线程是拿不到写锁,写锁互斥
        writeLock.lock();
        System.out.println(Thread.currentThread().getName() + " 获取到读锁资源");
        writeLock.unlock();
        System.out.println("=====USE ReentrantReadWriteLock-> writeLock=====");
    }
}
